using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using DDotNet.Data.BusinessObjects.Core;
using DDotNet.Data.BusinessObjects.Core.Resource;

namespace DDotNet.Data.BusinessObjects
{
    /// <summary>
    /// This is the base class from which readonly collections
    /// of readonly objects should be derived.
    /// </summary>
    [SuppressMessage(
        "Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
    [Serializable()]
    public abstract class ReadOnlyListBase<T, C> :
        ReadOnlyBindingList<C>, IReadOnlyCollection,
        ICloneable
        where T : ReadOnlyListBase<T, C>
    {
        #region Constructors

        protected ReadOnlyListBase()
        {
        }

        #endregion

        #region ICloneable

        object ICloneable.Clone()
        {
            return GetClone();
        }

        /// <summary>
        /// Creates a clone of the object.
        /// </summary>
        /// <returns>A new object containing the exact data of the original object.</returns>
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual object GetClone()
        {
            return ObjectCloner.Clone(this);
        }

        /// <summary>
        /// Creates a clone of the object.
        /// </summary>
        /// <returns>
        /// A new object containing the exact data of the original object.
        /// </returns>
        public virtual T Clone()
        {
            return (T) GetClone();
        }

        #endregion

        #region Data Access

        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "criteria")]
        private void DataPortal_Create(object criteria)
        {
            throw new NotSupportedException(ResourceWrapper.Instance.CreateNotSupportedException);
        }

        /// <summary>
        /// Override this method to allow retrieval of an existing business
        /// object based on data in the database.
        /// </summary>
        /// <param name="Criteria">An object containing criteria values to identify the object.</param>
        [SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
        protected virtual void DataPortal_Fetch(object criteria)
        {
            throw new NotSupportedException(ResourceWrapper.Instance.FetchNotSupportedException);
        }

        private void DataPortal_Update()
        {
            throw new NotSupportedException(ResourceWrapper.Instance.UpdateNotSupportedException);
        }

        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "criteria")]
        private void DataPortal_Delete(object criteria)
        {
            throw new NotSupportedException(ResourceWrapper.Instance.DeleteNotSupportedException);
        }

        /// <summary>
        /// Called by the server-side DataPortal prior to calling the 
        /// requested DataPortal_xyz method.
        /// </summary>
        /// <param name="e">The DataPortalContext object passed to the DataPortal.</param>
        [SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void DataPortal_OndataPortalInvoke(DataPortalEventArgs e)
        {
        }

        /// <summary>
        /// Called by the server-side DataPortal after calling the 
        /// requested DataPortal_xyz method.
        /// </summary>
        /// <param name="e">The DataPortalContext object passed to the DataPortal.</param>
        [SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void DataPortal_OnDataPortalInvokeComplete(DataPortalEventArgs e)
        {
        }

        /// <summary>
        /// Called by the server-side DataPortal if an exception
        /// occurs during data access.
        /// </summary>
        /// <param name="e">The DataPortalContext object passed to the DataPortal.</param>
        /// <param name="ex">The Exception thrown during data access.</param>
        [SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void DataPortal_OnDataPortalException(DataPortalEventArgs e, Exception ex)
        {
        }

        #endregion
    }
}